{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting torch==2.2\n",
      "  Downloading torch-2.2.0-cp310-cp310-manylinux1_x86_64.whl.metadata (25 kB)\n",
      "Requirement already satisfied: filelock in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (3.13.1)\n",
      "Collecting typing-extensions>=4.8.0 (from torch==2.2)\n",
      "  Downloading typing_extensions-4.9.0-py3-none-any.whl.metadata (3.0 kB)\n",
      "Requirement already satisfied: sympy in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (1.12)\n",
      "Requirement already satisfied: networkx in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (3.2.1)\n",
      "Requirement already satisfied: jinja2 in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (3.1.2)\n",
      "Requirement already satisfied: fsspec in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (2023.12.2)\n",
      "Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.1.105 in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cuda-runtime-cu12==12.1.105 in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cuda-cupti-cu12==12.1.105 in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cudnn-cu12==8.9.2.26 in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (8.9.2.26)\n",
      "Requirement already satisfied: nvidia-cublas-cu12==12.1.3.1 in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (12.1.3.1)\n",
      "Requirement already satisfied: nvidia-cufft-cu12==11.0.2.54 in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (11.0.2.54)\n",
      "Requirement already satisfied: nvidia-curand-cu12==10.3.2.106 in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (10.3.2.106)\n",
      "Requirement already satisfied: nvidia-cusolver-cu12==11.4.5.107 in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (11.4.5.107)\n",
      "Requirement already satisfied: nvidia-cusparse-cu12==12.1.0.106 in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (12.1.0.106)\n",
      "Collecting nvidia-nccl-cu12==2.19.3 (from torch==2.2)\n",
      "  Downloading nvidia_nccl_cu12-2.19.3-py3-none-manylinux1_x86_64.whl.metadata (1.8 kB)\n",
      "Requirement already satisfied: nvidia-nvtx-cu12==12.1.105 in /opt/conda/lib/python3.10/site-packages (from torch==2.2) (12.1.105)\n",
      "Collecting triton==2.2.0 (from torch==2.2)\n",
      "  Downloading triton-2.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (1.4 kB)\n",
      "Requirement already satisfied: nvidia-nvjitlink-cu12 in /opt/conda/lib/python3.10/site-packages (from nvidia-cusolver-cu12==11.4.5.107->torch==2.2) (12.3.101)\n",
      "Requirement already satisfied: MarkupSafe>=2.0 in /opt/conda/lib/python3.10/site-packages (from jinja2->torch==2.2) (2.1.3)\n",
      "Requirement already satisfied: mpmath>=0.19 in /opt/conda/lib/python3.10/site-packages (from sympy->torch==2.2) (1.3.0)\n",
      "Downloading torch-2.2.0-cp310-cp310-manylinux1_x86_64.whl (755.5 MB)\n",
      "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m755.5/755.5 MB\u001b[0m \u001b[31m3.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n",
      "\u001b[?25hDownloading nvidia_nccl_cu12-2.19.3-py3-none-manylinux1_x86_64.whl (166.0 MB)\n",
      "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m166.0/166.0 MB\u001b[0m \u001b[31m14.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n",
      "\u001b[?25hDownloading triton-2.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (167.9 MB)\n",
      "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m167.9/167.9 MB\u001b[0m \u001b[31m13.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:01\u001b[0m\n",
      "\u001b[?25hDownloading typing_extensions-4.9.0-py3-none-any.whl (32 kB)\n",
      "Installing collected packages: typing-extensions, triton, nvidia-nccl-cu12, torch\n",
      "  Attempting uninstall: typing-extensions\n",
      "    Found existing installation: typing_extensions 4.3.0\n",
      "    Uninstalling typing_extensions-4.3.0:\n",
      "      Successfully uninstalled typing_extensions-4.3.0\n",
      "  Attempting uninstall: triton\n",
      "    Found existing installation: triton 2.1.0\n",
      "    Uninstalling triton-2.1.0:\n",
      "      Successfully uninstalled triton-2.1.0\n",
      "  Attempting uninstall: nvidia-nccl-cu12\n",
      "    Found existing installation: nvidia-nccl-cu12 2.18.1\n",
      "    Uninstalling nvidia-nccl-cu12-2.18.1:\n",
      "      Successfully uninstalled nvidia-nccl-cu12-2.18.1\n",
      "  Attempting uninstall: torch\n",
      "    Found existing installation: torch 2.1.2\n",
      "    Uninstalling torch-2.1.2:\n",
      "      Successfully uninstalled torch-2.1.2\n",
      "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
      "torchaudio 2.1.2 requires torch==2.1.2, but you have torch 2.2.0 which is incompatible.\n",
      "torchvision 0.16.2 requires torch==2.1.2, but you have torch 2.2.0 which is incompatible.\n",
      "ydata-profiling 4.6.0 requires numpy<1.26,>=1.16.0, but you have numpy 1.26.2 which is incompatible.\n",
      "minimagen 0.0.9 requires attrs==21.4.0, but you have attrs 23.2.0 which is incompatible.\n",
      "minimagen 0.0.9 requires filelock==3.7.1, but you have filelock 3.13.1 which is incompatible.\n",
      "minimagen 0.0.9 requires fsspec==2022.5.0, but you have fsspec 2023.12.2 which is incompatible.\n",
      "minimagen 0.0.9 requires huggingface-hub==0.8.1, but you have huggingface-hub 0.20.1 which is incompatible.\n",
      "minimagen 0.0.9 requires numpy==1.23.1, but you have numpy 1.26.2 which is incompatible.\n",
      "minimagen 0.0.9 requires Pillow==9.2.0, but you have pillow 10.2.0 which is incompatible.\n",
      "minimagen 0.0.9 requires tokenizers==0.12.1, but you have tokenizers 0.15.0 which is incompatible.\n",
      "minimagen 0.0.9 requires torch==1.12.0, but you have torch 2.2.0 which is incompatible.\n",
      "minimagen 0.0.9 requires torchvision==0.13.0, but you have torchvision 0.16.2 which is incompatible.\n",
      "minimagen 0.0.9 requires tqdm==4.64.0, but you have tqdm 4.66.1 which is incompatible.\n",
      "minimagen 0.0.9 requires transformers==4.20.1, but you have transformers 4.36.2 which is incompatible.\n",
      "minimagen 0.0.9 requires typing_extensions==4.3.0, but you have typing-extensions 4.9.0 which is incompatible.\u001b[0m\u001b[31m\n",
      "\u001b[0mSuccessfully installed nvidia-nccl-cu12-2.19.3 torch-2.2.0 triton-2.2.0 typing-extensions-4.9.0\n",
      "Collecting torchvision==0.17\n",
      "  Downloading torchvision-0.17.0-cp310-cp310-manylinux1_x86_64.whl.metadata (6.6 kB)\n",
      "Requirement already satisfied: numpy in /opt/conda/lib/python3.10/site-packages (from torchvision==0.17) (1.26.2)\n",
      "Requirement already satisfied: requests in /opt/conda/lib/python3.10/site-packages (from torchvision==0.17) (2.28.1)\n",
      "Requirement already satisfied: torch==2.2.0 in /opt/conda/lib/python3.10/site-packages (from torchvision==0.17) (2.2.0)\n",
      "Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in /opt/conda/lib/python3.10/site-packages (from torchvision==0.17) (10.2.0)\n",
      "Requirement already satisfied: filelock in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (3.13.1)\n",
      "Requirement already satisfied: typing-extensions>=4.8.0 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (4.9.0)\n",
      "Requirement already satisfied: sympy in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (1.12)\n",
      "Requirement already satisfied: networkx in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (3.2.1)\n",
      "Requirement already satisfied: jinja2 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (3.1.2)\n",
      "Requirement already satisfied: fsspec in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (2023.12.2)\n",
      "Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.1.105 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cuda-runtime-cu12==12.1.105 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cuda-cupti-cu12==12.1.105 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (12.1.105)\n",
      "Requirement already satisfied: nvidia-cudnn-cu12==8.9.2.26 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (8.9.2.26)\n",
      "Requirement already satisfied: nvidia-cublas-cu12==12.1.3.1 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (12.1.3.1)\n",
      "Requirement already satisfied: nvidia-cufft-cu12==11.0.2.54 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (11.0.2.54)\n",
      "Requirement already satisfied: nvidia-curand-cu12==10.3.2.106 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (10.3.2.106)\n",
      "Requirement already satisfied: nvidia-cusolver-cu12==11.4.5.107 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (11.4.5.107)\n",
      "Requirement already satisfied: nvidia-cusparse-cu12==12.1.0.106 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (12.1.0.106)\n",
      "Requirement already satisfied: nvidia-nccl-cu12==2.19.3 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (2.19.3)\n",
      "Requirement already satisfied: nvidia-nvtx-cu12==12.1.105 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (12.1.105)\n",
      "Requirement already satisfied: triton==2.2.0 in /opt/conda/lib/python3.10/site-packages (from torch==2.2.0->torchvision==0.17) (2.2.0)\n",
      "Requirement already satisfied: nvidia-nvjitlink-cu12 in /opt/conda/lib/python3.10/site-packages (from nvidia-cusolver-cu12==11.4.5.107->torch==2.2.0->torchvision==0.17) (12.3.101)\n",
      "Requirement already satisfied: charset-normalizer<3,>=2 in /opt/conda/lib/python3.10/site-packages (from requests->torchvision==0.17) (2.1.0)\n",
      "Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.10/site-packages (from requests->torchvision==0.17) (3.3)\n",
      "Requirement already satisfied: urllib3<1.27,>=1.21.1 in /opt/conda/lib/python3.10/site-packages (from requests->torchvision==0.17) (1.26.10)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.10/site-packages (from requests->torchvision==0.17) (2022.6.15)\n",
      "Requirement already satisfied: MarkupSafe>=2.0 in /opt/conda/lib/python3.10/site-packages (from jinja2->torch==2.2.0->torchvision==0.17) (2.1.3)\n",
      "Requirement already satisfied: mpmath>=0.19 in /opt/conda/lib/python3.10/site-packages (from sympy->torch==2.2.0->torchvision==0.17) (1.3.0)\n",
      "Downloading torchvision-0.17.0-cp310-cp310-manylinux1_x86_64.whl (6.9 MB)\n",
      "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m6.9/6.9 MB\u001b[0m \u001b[31m95.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m:00:01\u001b[0m00:01\u001b[0m\n",
      "\u001b[?25hInstalling collected packages: torchvision\n",
      "  Attempting uninstall: torchvision\n",
      "    Found existing installation: torchvision 0.16.2\n",
      "    Uninstalling torchvision-0.16.2:\n",
      "      Successfully uninstalled torchvision-0.16.2\n",
      "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
      "minimagen 0.0.9 requires attrs==21.4.0, but you have attrs 23.2.0 which is incompatible.\n",
      "minimagen 0.0.9 requires filelock==3.7.1, but you have filelock 3.13.1 which is incompatible.\n",
      "minimagen 0.0.9 requires fsspec==2022.5.0, but you have fsspec 2023.12.2 which is incompatible.\n",
      "minimagen 0.0.9 requires huggingface-hub==0.8.1, but you have huggingface-hub 0.20.1 which is incompatible.\n",
      "minimagen 0.0.9 requires numpy==1.23.1, but you have numpy 1.26.2 which is incompatible.\n",
      "minimagen 0.0.9 requires Pillow==9.2.0, but you have pillow 10.2.0 which is incompatible.\n",
      "minimagen 0.0.9 requires tokenizers==0.12.1, but you have tokenizers 0.15.0 which is incompatible.\n",
      "minimagen 0.0.9 requires torch==1.12.0, but you have torch 2.2.0 which is incompatible.\n",
      "minimagen 0.0.9 requires torchvision==0.13.0, but you have torchvision 0.17.0 which is incompatible.\n",
      "minimagen 0.0.9 requires tqdm==4.64.0, but you have tqdm 4.66.1 which is incompatible.\n",
      "minimagen 0.0.9 requires transformers==4.20.1, but you have transformers 4.36.2 which is incompatible.\n",
      "minimagen 0.0.9 requires typing_extensions==4.3.0, but you have typing-extensions 4.9.0 which is incompatible.\u001b[0m\u001b[31m\n",
      "\u001b[0mSuccessfully installed torchvision-0.17.0\n",
      "Collecting nltk==3.7\n",
      "  Downloading nltk-3.7-py3-none-any.whl (1.5 MB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.5/1.5 MB\u001b[0m \u001b[31m28.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: click in /opt/conda/lib/python3.10/site-packages (from nltk==3.7) (8.1.7)\n",
      "Requirement already satisfied: joblib in /opt/conda/lib/python3.10/site-packages (from nltk==3.7) (1.3.2)\n",
      "Requirement already satisfied: regex>=2021.8.3 in /opt/conda/lib/python3.10/site-packages (from nltk==3.7) (2022.7.9)\n",
      "Requirement already satisfied: tqdm in /opt/conda/lib/python3.10/site-packages (from nltk==3.7) (4.66.1)\n",
      "Installing collected packages: nltk\n",
      "Successfully installed nltk-3.7\n"
     ]
    }
   ],
   "source": [
    "!pip install torch==2.2\n",
    "!pip install torchvision==0.17\n",
    "!pip install nltk==3.7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/lib/python3.10/site-packages/transformers/utils/generic.py:441: UserWarning: torch.utils._pytree._register_pytree_node is deprecated. Please use torch.utils._pytree.register_pytree_node instead.\n",
      "  _torch_pytree._register_pytree_node(\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    " \n",
    "import torch\n",
    "import torchvision\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import torchvision.transforms as transforms\n",
    "\n",
    "torch.use_deterministic_algorithms(True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LeNet(\n",
      "  (cn1): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))\n",
      "  (cn2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))\n",
      "  (fc1): Linear(in_features=400, out_features=120, bias=True)\n",
      "  (fc2): Linear(in_features=120, out_features=84, bias=True)\n",
      "  (fc3): Linear(in_features=84, out_features=10, bias=True)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "class LeNet(nn.Module):\n",
    "\n",
    "    def __init__(self):\n",
    "        super(LeNet, self).__init__()\n",
    "        # 3 input image channel, 6 output feature maps and 5x5 conv kernel\n",
    "        self.cn1 = nn.Conv2d(3, 6, 5)\n",
    "        # 6 input image channel, 16 output feature maps and 5x5 conv kernel\n",
    "        self.cn2 = nn.Conv2d(6, 16, 5)\n",
    "        # fully connected layers of size 120, 84 and 10\n",
    "        self.fc1 = nn.Linear(16 * 5 * 5, 120)  # 5*5 is the spatial dimension at this layer\n",
    "        self.fc2 = nn.Linear(120, 84)\n",
    "        self.fc3 = nn.Linear(84, 10)\n",
    "\n",
    "    def forward(self, x):\n",
    "        # Convolution with 5x5 kernel\n",
    "        x = F.relu(self.cn1(x))\n",
    "        # Max pooling over a (2, 2) window\n",
    "        x = F.max_pool2d(x, (2, 2))\n",
    "        # Convolution with 5x5 kernel\n",
    "        x = F.relu(self.cn2(x))\n",
    "        # Max pooling over a (2, 2) window\n",
    "        x = F.max_pool2d(x, (2, 2))\n",
    "        # Flatten spatial and depth dimensions into a single vector\n",
    "        x = x.view(-1, self.flattened_features(x))\n",
    "        # Fully connected operations\n",
    "        x = F.relu(self.fc1(x))\n",
    "        x = F.relu(self.fc2(x))\n",
    "        x = self.fc3(x)\n",
    "        return x\n",
    "\n",
    "    def flattened_features(self, x):\n",
    "        # all except the first (batch) dimension\n",
    "        size = x.size()[1:]  \n",
    "        num_feats = 1\n",
    "        for s in size:\n",
    "            num_feats *= s\n",
    "        return num_feats\n",
    "\n",
    "\n",
    "lenet = LeNet()\n",
    "print(lenet)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train(net, trainloader, optim, epoch):\n",
    "    # initialize loss\n",
    "    loss_total = 0.0\n",
    "    \n",
    "    for i, data in enumerate(trainloader, 0):\n",
    "        # get the inputs; data is a list of [inputs, labels]\n",
    "        # ip refers to the input images, and ground_truth refers to the output classes the images belong to\n",
    "        ip, ground_truth = data\n",
    "\n",
    "        # zero the parameter gradients\n",
    "        optim.zero_grad()\n",
    "\n",
    "        # forward pass + backward pass + optimization step\n",
    "        op = net(ip)\n",
    "        loss = nn.CrossEntropyLoss()(op, ground_truth)\n",
    "        loss.backward()\n",
    "        optim.step()\n",
    "\n",
    "        # update loss\n",
    "        loss_total += loss.item()\n",
    "        \n",
    "        # print loss statistics\n",
    "        if (i+1) % 1000 == 0:    # print at the interval of 1000 mini-batches\n",
    "            print('[Epoch number : %d, Mini-batches: %5d] loss: %.3f' %\n",
    "                  (epoch + 1, i + 1, loss_total / 200))\n",
    "            loss_total = 0.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def test(net, testloader):\n",
    "    success = 0\n",
    "    counter = 0\n",
    "    with torch.no_grad():\n",
    "        for data in testloader:\n",
    "            im, ground_truth = data\n",
    "            op = net(im)\n",
    "            _, pred = torch.max(op.data, 1)\n",
    "            counter += ground_truth.size(0)\n",
    "            success += (pred == ground_truth).sum().item()\n",
    "\n",
    "    print('LeNet accuracy on 10000 images from test dataset: %d %%' % (\n",
    "        100 * success / counter))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Files already downloaded and verified\n",
      "Files already downloaded and verified\n"
     ]
    }
   ],
   "source": [
    "# The mean and std are kept as 0.5 for normalizing pixel values as the pixel values are originally in the range 0 to 1\n",
    "train_transform = transforms.Compose([transforms.RandomHorizontalFlip(),\n",
    "                                      transforms.RandomCrop(32, 4),\n",
    "                                      transforms.ToTensor(),\n",
    "                                      transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])\n",
    "\n",
    "trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=train_transform)\n",
    "trainloader = torch.utils.data.DataLoader(trainset, batch_size=8, shuffle=True)\n",
    "\n",
    "\n",
    "test_transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])\n",
    "\n",
    "testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=test_transform)\n",
    "testloader = torch.utils.data.DataLoader(testset, batch_size=10000, shuffle=False)\n",
    "\n",
    "\n",
    "# ordering is important\n",
    "classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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7YM/rofTFi+//LIhIvPCCy/Uj/nZz35mHMcxb7/9dsvq3goONTlDnn/+eUNEZvv27caYY6t9DoejzuxSqVRo06ZNtHLlyvpnruvSypUracOGDbNYs9lndHSUiIi6urqIiGjTpk1UrVZFWy1btoz6+/uPqbZavXo1feYznxHtQKTt8+///u907rnn0u/93u/RggUL6JxzzqF//Md/rJdv27aNBgcHRfvkcjlasWLFMdE+H/7wh2n9+vX02muvERHRL3/5S3rmmWfo4osvJiJtH87htMWGDRuoo6ODzj333PoxK1euJNd16bnnnmt5nWeb0dFRchyHOjo6iEjbBznqstru37+foiiinp4e8XlPTw+9+uqrs1Sr2SeOY7r++uvpwgsvpDPOOIOIiAYHBykIgnrn/g09PT00ODg4C7VsPQ888AD993//N73wwgsNZcd6+7z55pt0991309q1a+lrX/savfDCC/Snf/qnFAQBrVq1qt4Ghxprx0L73HTTTZTP52nZsmXkeR5FUUS33XYbXXXVVUREx3z7cA6nLQYHB2nBggWi3Pd96urqOubaq1Qq0Y033khXXnllPbOtto/kqJt8KIdm9erVtGXLFnrmmWdmuypHDTt37qTrrruOHn/8cUomk7NdnaOOOI7p3HPPpb/+678mIqJzzjmHtmzZQt/97ndp1apVs1y72eff/u3f6Pvf/z7df//9dPrpp9PmzZvp+uuvp76+Pm0f5YipVqv0+7//+2SMobvvvnu2q3PUctSZXebNm0ee5zVEJAwNDVFvb+8s1Wp2WbNmDT3yyCP05JNP0qJFi+qf9/b2UqVSoZGREXH8sdJWmzZtor1799KHPvQh8n2ffN+np556ir797W+T7/vU09NzTLfPwoUL6bTTThOfnXrqqbRjxw4ionobHKtj7c/+7M/opptuos9//vN05pln0h/+4R/SDTfcQOvWrSMibR/O4bRFb28v7d27V5TXajUaHh4+ZtrrNxOP7du30+OPP15f9SDS9kGOuslHEAS0fPlyWr9+ff2zOI5p/fr1NDAwMIs1az3GGFqzZg099NBD9MQTT9DSpUtF+fLlyymRSIi22rp1K+3YseOYaKtPfOIT9NJLL9HmzZvrf+eeey5dddVV9e1juX0uvPDChtDs1157jY4//ngiIlq6dCn19vaK9snn8/Tcc88dE+1TKBTIdeUr0PM8iuOYiLR9OIfTFgMDAzQyMkKbNm2qH/PEE09QHMe0YsWKlte51fxm4vH666/Tf/7nf1J3d7coP9bbp4HZ9ng9FA888IAJw9Dcd9995uWXXzZf/vKXTUdHhxkcHJztqrWUP/7jPza5XM78/Oc/N3v27Kn/FQqF+jHXXnut6e/vN0888YTZuHGjGRgYMAMDA7NY69mFR7sYc2y3z/PPP2983ze33Xabef311833v/9909bWZv7lX/6lfsztt99uOjo6zI9//GPzq1/9ylx66aVzNpQUWbVqlTnuuOPqobY/+tGPzLx588xXv/rV+jHHUvuMjY2ZF1980bz44ouGiMzf/d3fmRdffLEerXE4bfHpT3/anHPOOea5554zzzzzjDn55JPnTChps/apVCrms5/9rFm0aJHZvHmzeF+Xy+X6OeZy+0yVo3LyYYwxf//3f2/6+/tNEATm/PPPN88+++xsV6nlENEh/+699976McVi0fzJn/yJ6ezsNG1tbeZ3f/d3zZ49e2av0rMMTj6O9fb5j//4D3PGGWeYMAzNsmXLzD/8wz+I8jiOzS233GJ6enpMGIbmE5/4hNm6dess1ba15PN5c91115n+/n6TTCbNCSecYL7+9a+LH4tjqX2efPLJQ75vVq1aZYw5vLY4cOCAufLKK00mkzHZbNZ88YtfNGNjY7NwN9NPs/bZtm3bpO/rJ598sn6Oudw+U8Uxhsn5KYqiKIqizDBHnc+HoiiKoihzG518KIqiKIrSUnTyoSiKoihKS9HJh6IoiqIoLUUnH4qiKIqitBSdfCiKoiiK0lJ08qEoiqIoSkvRyYeiKIqiKC1FJx+KoiiKorQUnXwoiqIoitJSdPKhKIqiKEpL+X/brsH7mMLkEAAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    horse  ||  deer  ||  plane  ||  dog\n"
     ]
    }
   ],
   "source": [
    "# define a function that displays an image\n",
    "def imageshow(image):\n",
    "    # un-normalize the image\n",
    "    image = image/2 + 0.5     \n",
    "    npimage = image.numpy()\n",
    "    plt.imshow(np.transpose(npimage, (1, 2, 0)))\n",
    "    plt.show()\n",
    "\n",
    "\n",
    "# sample images from training set\n",
    "dataiter = iter(trainloader)\n",
    "images, labels = next(dataiter)\n",
    "\n",
    "# display images in a grid\n",
    "num_images = 4\n",
    "imageshow(torchvision.utils.make_grid(images[:num_images]))\n",
    "# print labels\n",
    "print('    '+'  ||  '.join(classes[labels[j]] for j in range(num_images)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Epoch number : 1, Mini-batches:  1000] loss: 9.887\n",
      "[Epoch number : 1, Mini-batches:  2000] loss: 8.766\n",
      "[Epoch number : 1, Mini-batches:  3000] loss: 8.350\n",
      "[Epoch number : 1, Mini-batches:  4000] loss: 8.136\n",
      "[Epoch number : 1, Mini-batches:  5000] loss: 7.806\n",
      "[Epoch number : 1, Mini-batches:  6000] loss: 7.584\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 46 %\n",
      "\n",
      "[Epoch number : 2, Mini-batches:  1000] loss: 7.502\n",
      "[Epoch number : 2, Mini-batches:  2000] loss: 7.380\n",
      "[Epoch number : 2, Mini-batches:  3000] loss: 7.173\n",
      "[Epoch number : 2, Mini-batches:  4000] loss: 7.106\n",
      "[Epoch number : 2, Mini-batches:  5000] loss: 7.109\n",
      "[Epoch number : 2, Mini-batches:  6000] loss: 7.039\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 51 %\n",
      "\n",
      "[Epoch number : 3, Mini-batches:  1000] loss: 6.959\n",
      "[Epoch number : 3, Mini-batches:  2000] loss: 6.903\n",
      "[Epoch number : 3, Mini-batches:  3000] loss: 6.900\n",
      "[Epoch number : 3, Mini-batches:  4000] loss: 7.021\n",
      "[Epoch number : 3, Mini-batches:  5000] loss: 6.664\n",
      "[Epoch number : 3, Mini-batches:  6000] loss: 6.599\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 54 %\n",
      "\n",
      "[Epoch number : 4, Mini-batches:  1000] loss: 6.680\n",
      "[Epoch number : 4, Mini-batches:  2000] loss: 6.588\n",
      "[Epoch number : 4, Mini-batches:  3000] loss: 6.650\n",
      "[Epoch number : 4, Mini-batches:  4000] loss: 6.549\n",
      "[Epoch number : 4, Mini-batches:  5000] loss: 6.576\n",
      "[Epoch number : 4, Mini-batches:  6000] loss: 6.487\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 57 %\n",
      "\n",
      "[Epoch number : 5, Mini-batches:  1000] loss: 6.418\n",
      "[Epoch number : 5, Mini-batches:  2000] loss: 6.424\n",
      "[Epoch number : 5, Mini-batches:  3000] loss: 6.482\n",
      "[Epoch number : 5, Mini-batches:  4000] loss: 6.401\n",
      "[Epoch number : 5, Mini-batches:  5000] loss: 6.400\n",
      "[Epoch number : 5, Mini-batches:  6000] loss: 6.274\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 58 %\n",
      "\n",
      "[Epoch number : 6, Mini-batches:  1000] loss: 6.238\n",
      "[Epoch number : 6, Mini-batches:  2000] loss: 6.196\n",
      "[Epoch number : 6, Mini-batches:  3000] loss: 6.319\n",
      "[Epoch number : 6, Mini-batches:  4000] loss: 6.271\n",
      "[Epoch number : 6, Mini-batches:  5000] loss: 6.148\n",
      "[Epoch number : 6, Mini-batches:  6000] loss: 6.217\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 58 %\n",
      "\n",
      "[Epoch number : 7, Mini-batches:  1000] loss: 6.156\n",
      "[Epoch number : 7, Mini-batches:  2000] loss: 6.053\n",
      "[Epoch number : 7, Mini-batches:  3000] loss: 6.147\n",
      "[Epoch number : 7, Mini-batches:  4000] loss: 6.060\n",
      "[Epoch number : 7, Mini-batches:  5000] loss: 6.067\n",
      "[Epoch number : 7, Mini-batches:  6000] loss: 6.200\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 59 %\n",
      "\n",
      "[Epoch number : 8, Mini-batches:  1000] loss: 5.992\n",
      "[Epoch number : 8, Mini-batches:  2000] loss: 6.001\n",
      "[Epoch number : 8, Mini-batches:  3000] loss: 6.057\n",
      "[Epoch number : 8, Mini-batches:  4000] loss: 5.926\n",
      "[Epoch number : 8, Mini-batches:  5000] loss: 6.069\n",
      "[Epoch number : 8, Mini-batches:  6000] loss: 6.044\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 61 %\n",
      "\n",
      "[Epoch number : 9, Mini-batches:  1000] loss: 5.948\n",
      "[Epoch number : 9, Mini-batches:  2000] loss: 5.840\n",
      "[Epoch number : 9, Mini-batches:  3000] loss: 5.897\n",
      "[Epoch number : 9, Mini-batches:  4000] loss: 5.856\n",
      "[Epoch number : 9, Mini-batches:  5000] loss: 5.847\n",
      "[Epoch number : 9, Mini-batches:  6000] loss: 6.045\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 60 %\n",
      "\n",
      "[Epoch number : 10, Mini-batches:  1000] loss: 5.873\n",
      "[Epoch number : 10, Mini-batches:  2000] loss: 5.963\n",
      "[Epoch number : 10, Mini-batches:  3000] loss: 5.907\n",
      "[Epoch number : 10, Mini-batches:  4000] loss: 5.846\n",
      "[Epoch number : 10, Mini-batches:  5000] loss: 5.864\n",
      "[Epoch number : 10, Mini-batches:  6000] loss: 5.741\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 61 %\n",
      "\n",
      "[Epoch number : 11, Mini-batches:  1000] loss: 5.710\n",
      "[Epoch number : 11, Mini-batches:  2000] loss: 5.795\n",
      "[Epoch number : 11, Mini-batches:  3000] loss: 5.881\n",
      "[Epoch number : 11, Mini-batches:  4000] loss: 5.849\n",
      "[Epoch number : 11, Mini-batches:  5000] loss: 5.751\n",
      "[Epoch number : 11, Mini-batches:  6000] loss: 5.729\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 63 %\n",
      "\n",
      "[Epoch number : 12, Mini-batches:  1000] loss: 5.732\n",
      "[Epoch number : 12, Mini-batches:  2000] loss: 5.732\n",
      "[Epoch number : 12, Mini-batches:  3000] loss: 5.701\n",
      "[Epoch number : 12, Mini-batches:  4000] loss: 5.761\n",
      "[Epoch number : 12, Mini-batches:  5000] loss: 5.734\n",
      "[Epoch number : 12, Mini-batches:  6000] loss: 5.684\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 62 %\n",
      "\n",
      "[Epoch number : 13, Mini-batches:  1000] loss: 5.674\n",
      "[Epoch number : 13, Mini-batches:  2000] loss: 5.703\n",
      "[Epoch number : 13, Mini-batches:  3000] loss: 5.653\n",
      "[Epoch number : 13, Mini-batches:  4000] loss: 5.652\n",
      "[Epoch number : 13, Mini-batches:  5000] loss: 5.700\n",
      "[Epoch number : 13, Mini-batches:  6000] loss: 5.794\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 62 %\n",
      "\n",
      "[Epoch number : 14, Mini-batches:  1000] loss: 5.745\n",
      "[Epoch number : 14, Mini-batches:  2000] loss: 5.605\n",
      "[Epoch number : 14, Mini-batches:  3000] loss: 5.685\n",
      "[Epoch number : 14, Mini-batches:  4000] loss: 5.550\n",
      "[Epoch number : 14, Mini-batches:  5000] loss: 5.623\n",
      "[Epoch number : 14, Mini-batches:  6000] loss: 5.631\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 61 %\n",
      "\n",
      "[Epoch number : 15, Mini-batches:  1000] loss: 5.637\n",
      "[Epoch number : 15, Mini-batches:  2000] loss: 5.594\n",
      "[Epoch number : 15, Mini-batches:  3000] loss: 5.581\n",
      "[Epoch number : 15, Mini-batches:  4000] loss: 5.522\n",
      "[Epoch number : 15, Mini-batches:  5000] loss: 5.532\n",
      "[Epoch number : 15, Mini-batches:  6000] loss: 5.615\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 62 %\n",
      "\n",
      "[Epoch number : 16, Mini-batches:  1000] loss: 5.627\n",
      "[Epoch number : 16, Mini-batches:  2000] loss: 5.543\n",
      "[Epoch number : 16, Mini-batches:  3000] loss: 5.557\n",
      "[Epoch number : 16, Mini-batches:  4000] loss: 5.572\n",
      "[Epoch number : 16, Mini-batches:  5000] loss: 5.535\n",
      "[Epoch number : 16, Mini-batches:  6000] loss: 5.603\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 62 %\n",
      "\n",
      "[Epoch number : 17, Mini-batches:  1000] loss: 5.411\n",
      "[Epoch number : 17, Mini-batches:  2000] loss: 5.526\n",
      "[Epoch number : 17, Mini-batches:  3000] loss: 5.572\n",
      "[Epoch number : 17, Mini-batches:  4000] loss: 5.533\n",
      "[Epoch number : 17, Mini-batches:  5000] loss: 5.590\n",
      "[Epoch number : 17, Mini-batches:  6000] loss: 5.395\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 64 %\n",
      "\n",
      "[Epoch number : 18, Mini-batches:  1000] loss: 5.455\n",
      "[Epoch number : 18, Mini-batches:  2000] loss: 5.596\n",
      "[Epoch number : 18, Mini-batches:  3000] loss: 5.455\n",
      "[Epoch number : 18, Mini-batches:  4000] loss: 5.430\n",
      "[Epoch number : 18, Mini-batches:  5000] loss: 5.441\n",
      "[Epoch number : 18, Mini-batches:  6000] loss: 5.424\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 64 %\n",
      "\n",
      "[Epoch number : 19, Mini-batches:  1000] loss: 5.441\n",
      "[Epoch number : 19, Mini-batches:  2000] loss: 5.513\n",
      "[Epoch number : 19, Mini-batches:  3000] loss: 5.546\n",
      "[Epoch number : 19, Mini-batches:  4000] loss: 5.492\n",
      "[Epoch number : 19, Mini-batches:  5000] loss: 5.348\n",
      "[Epoch number : 19, Mini-batches:  6000] loss: 5.475\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 64 %\n",
      "\n",
      "[Epoch number : 20, Mini-batches:  1000] loss: 5.308\n",
      "[Epoch number : 20, Mini-batches:  2000] loss: 5.449\n",
      "[Epoch number : 20, Mini-batches:  3000] loss: 5.489\n",
      "[Epoch number : 20, Mini-batches:  4000] loss: 5.411\n",
      "[Epoch number : 20, Mini-batches:  5000] loss: 5.492\n",
      "[Epoch number : 20, Mini-batches:  6000] loss: 5.449\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 64 %\n",
      "\n",
      "[Epoch number : 21, Mini-batches:  1000] loss: 5.417\n",
      "[Epoch number : 21, Mini-batches:  2000] loss: 5.461\n",
      "[Epoch number : 21, Mini-batches:  3000] loss: 5.266\n",
      "[Epoch number : 21, Mini-batches:  4000] loss: 5.411\n",
      "[Epoch number : 21, Mini-batches:  5000] loss: 5.460\n",
      "[Epoch number : 21, Mini-batches:  6000] loss: 5.451\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 65 %\n",
      "\n",
      "[Epoch number : 22, Mini-batches:  1000] loss: 5.332\n",
      "[Epoch number : 22, Mini-batches:  2000] loss: 5.474\n",
      "[Epoch number : 22, Mini-batches:  3000] loss: 5.373\n",
      "[Epoch number : 22, Mini-batches:  4000] loss: 5.412\n",
      "[Epoch number : 22, Mini-batches:  5000] loss: 5.334\n",
      "[Epoch number : 22, Mini-batches:  6000] loss: 5.371\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 63 %\n",
      "\n",
      "[Epoch number : 23, Mini-batches:  1000] loss: 5.378\n",
      "[Epoch number : 23, Mini-batches:  2000] loss: 5.376\n",
      "[Epoch number : 23, Mini-batches:  3000] loss: 5.365\n",
      "[Epoch number : 23, Mini-batches:  4000] loss: 5.452\n",
      "[Epoch number : 23, Mini-batches:  5000] loss: 5.362\n",
      "[Epoch number : 23, Mini-batches:  6000] loss: 5.328\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 65 %\n",
      "\n",
      "[Epoch number : 24, Mini-batches:  1000] loss: 5.217\n",
      "[Epoch number : 24, Mini-batches:  2000] loss: 5.435\n",
      "[Epoch number : 24, Mini-batches:  3000] loss: 5.383\n",
      "[Epoch number : 24, Mini-batches:  4000] loss: 5.400\n",
      "[Epoch number : 24, Mini-batches:  5000] loss: 5.364\n",
      "[Epoch number : 24, Mini-batches:  6000] loss: 5.263\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 64 %\n",
      "\n",
      "[Epoch number : 25, Mini-batches:  1000] loss: 5.255\n",
      "[Epoch number : 25, Mini-batches:  2000] loss: 5.392\n",
      "[Epoch number : 25, Mini-batches:  3000] loss: 5.320\n",
      "[Epoch number : 25, Mini-batches:  4000] loss: 5.278\n",
      "[Epoch number : 25, Mini-batches:  5000] loss: 5.261\n",
      "[Epoch number : 25, Mini-batches:  6000] loss: 5.187\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 64 %\n",
      "\n",
      "[Epoch number : 26, Mini-batches:  1000] loss: 5.267\n",
      "[Epoch number : 26, Mini-batches:  2000] loss: 5.323\n",
      "[Epoch number : 26, Mini-batches:  3000] loss: 5.307\n",
      "[Epoch number : 26, Mini-batches:  4000] loss: 5.257\n",
      "[Epoch number : 26, Mini-batches:  5000] loss: 5.373\n",
      "[Epoch number : 26, Mini-batches:  6000] loss: 5.279\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 66 %\n",
      "\n",
      "[Epoch number : 27, Mini-batches:  1000] loss: 5.342\n",
      "[Epoch number : 27, Mini-batches:  2000] loss: 5.241\n",
      "[Epoch number : 27, Mini-batches:  3000] loss: 5.224\n",
      "[Epoch number : 27, Mini-batches:  4000] loss: 5.312\n",
      "[Epoch number : 27, Mini-batches:  5000] loss: 5.297\n",
      "[Epoch number : 27, Mini-batches:  6000] loss: 5.257\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 65 %\n",
      "\n",
      "[Epoch number : 28, Mini-batches:  1000] loss: 5.200\n",
      "[Epoch number : 28, Mini-batches:  2000] loss: 5.226\n",
      "[Epoch number : 28, Mini-batches:  3000] loss: 5.478\n",
      "[Epoch number : 28, Mini-batches:  4000] loss: 5.274\n",
      "[Epoch number : 28, Mini-batches:  5000] loss: 5.341\n",
      "[Epoch number : 28, Mini-batches:  6000] loss: 5.284\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 63 %\n",
      "\n",
      "[Epoch number : 29, Mini-batches:  1000] loss: 5.187\n",
      "[Epoch number : 29, Mini-batches:  2000] loss: 5.323\n",
      "[Epoch number : 29, Mini-batches:  3000] loss: 5.350\n",
      "[Epoch number : 29, Mini-batches:  4000] loss: 5.278\n",
      "[Epoch number : 29, Mini-batches:  5000] loss: 5.212\n",
      "[Epoch number : 29, Mini-batches:  6000] loss: 5.291\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 65 %\n",
      "\n",
      "[Epoch number : 30, Mini-batches:  1000] loss: 5.278\n",
      "[Epoch number : 30, Mini-batches:  2000] loss: 5.200\n",
      "[Epoch number : 30, Mini-batches:  3000] loss: 5.122\n",
      "[Epoch number : 30, Mini-batches:  4000] loss: 5.264\n",
      "[Epoch number : 30, Mini-batches:  5000] loss: 5.274\n",
      "[Epoch number : 30, Mini-batches:  6000] loss: 5.334\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 66 %\n",
      "\n",
      "[Epoch number : 31, Mini-batches:  1000] loss: 5.158\n",
      "[Epoch number : 31, Mini-batches:  2000] loss: 5.076\n",
      "[Epoch number : 31, Mini-batches:  3000] loss: 5.238\n",
      "[Epoch number : 31, Mini-batches:  4000] loss: 5.370\n",
      "[Epoch number : 31, Mini-batches:  5000] loss: 5.139\n",
      "[Epoch number : 31, Mini-batches:  6000] loss: 5.246\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 65 %\n",
      "\n",
      "[Epoch number : 32, Mini-batches:  1000] loss: 5.234\n",
      "[Epoch number : 32, Mini-batches:  2000] loss: 5.215\n",
      "[Epoch number : 32, Mini-batches:  3000] loss: 5.256\n",
      "[Epoch number : 32, Mini-batches:  4000] loss: 5.161\n",
      "[Epoch number : 32, Mini-batches:  5000] loss: 5.028\n",
      "[Epoch number : 32, Mini-batches:  6000] loss: 5.264\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 63 %\n",
      "\n",
      "[Epoch number : 33, Mini-batches:  1000] loss: 5.198\n",
      "[Epoch number : 33, Mini-batches:  2000] loss: 5.196\n",
      "[Epoch number : 33, Mini-batches:  3000] loss: 5.177\n",
      "[Epoch number : 33, Mini-batches:  4000] loss: 5.111\n",
      "[Epoch number : 33, Mini-batches:  5000] loss: 5.333\n",
      "[Epoch number : 33, Mini-batches:  6000] loss: 5.214\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 67 %\n",
      "\n",
      "[Epoch number : 34, Mini-batches:  1000] loss: 5.189\n",
      "[Epoch number : 34, Mini-batches:  2000] loss: 5.221\n",
      "[Epoch number : 34, Mini-batches:  3000] loss: 5.151\n",
      "[Epoch number : 34, Mini-batches:  4000] loss: 5.220\n",
      "[Epoch number : 34, Mini-batches:  5000] loss: 5.301\n",
      "[Epoch number : 34, Mini-batches:  6000] loss: 5.172\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 66 %\n",
      "\n",
      "[Epoch number : 35, Mini-batches:  1000] loss: 5.087\n",
      "[Epoch number : 35, Mini-batches:  2000] loss: 5.227\n",
      "[Epoch number : 35, Mini-batches:  3000] loss: 5.275\n",
      "[Epoch number : 35, Mini-batches:  4000] loss: 5.156\n",
      "[Epoch number : 35, Mini-batches:  5000] loss: 5.131\n",
      "[Epoch number : 35, Mini-batches:  6000] loss: 5.228\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 65 %\n",
      "\n",
      "[Epoch number : 36, Mini-batches:  1000] loss: 5.083\n",
      "[Epoch number : 36, Mini-batches:  2000] loss: 5.078\n",
      "[Epoch number : 36, Mini-batches:  3000] loss: 5.193\n",
      "[Epoch number : 36, Mini-batches:  4000] loss: 5.221\n",
      "[Epoch number : 36, Mini-batches:  5000] loss: 5.222\n",
      "[Epoch number : 36, Mini-batches:  6000] loss: 5.238\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 67 %\n",
      "\n",
      "[Epoch number : 37, Mini-batches:  1000] loss: 5.130\n",
      "[Epoch number : 37, Mini-batches:  2000] loss: 5.166\n",
      "[Epoch number : 37, Mini-batches:  3000] loss: 5.093\n",
      "[Epoch number : 37, Mini-batches:  4000] loss: 5.246\n",
      "[Epoch number : 37, Mini-batches:  5000] loss: 5.137\n",
      "[Epoch number : 37, Mini-batches:  6000] loss: 5.147\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 67 %\n",
      "\n",
      "[Epoch number : 38, Mini-batches:  1000] loss: 5.033\n",
      "[Epoch number : 38, Mini-batches:  2000] loss: 5.109\n",
      "[Epoch number : 38, Mini-batches:  3000] loss: 5.077\n",
      "[Epoch number : 38, Mini-batches:  4000] loss: 5.176\n",
      "[Epoch number : 38, Mini-batches:  5000] loss: 5.188\n",
      "[Epoch number : 38, Mini-batches:  6000] loss: 5.229\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 66 %\n",
      "\n",
      "[Epoch number : 39, Mini-batches:  1000] loss: 5.122\n",
      "[Epoch number : 39, Mini-batches:  2000] loss: 5.079\n",
      "[Epoch number : 39, Mini-batches:  3000] loss: 5.116\n",
      "[Epoch number : 39, Mini-batches:  4000] loss: 4.991\n",
      "[Epoch number : 39, Mini-batches:  5000] loss: 5.109\n",
      "[Epoch number : 39, Mini-batches:  6000] loss: 5.157\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 65 %\n",
      "\n",
      "[Epoch number : 40, Mini-batches:  1000] loss: 5.091\n",
      "[Epoch number : 40, Mini-batches:  2000] loss: 5.166\n",
      "[Epoch number : 40, Mini-batches:  3000] loss: 5.136\n",
      "[Epoch number : 40, Mini-batches:  4000] loss: 5.131\n",
      "[Epoch number : 40, Mini-batches:  5000] loss: 5.179\n",
      "[Epoch number : 40, Mini-batches:  6000] loss: 5.104\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 67 %\n",
      "\n",
      "[Epoch number : 41, Mini-batches:  1000] loss: 5.090\n",
      "[Epoch number : 41, Mini-batches:  2000] loss: 5.137\n",
      "[Epoch number : 41, Mini-batches:  3000] loss: 5.074\n",
      "[Epoch number : 41, Mini-batches:  4000] loss: 5.262\n",
      "[Epoch number : 41, Mini-batches:  5000] loss: 5.030\n",
      "[Epoch number : 41, Mini-batches:  6000] loss: 5.105\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 67 %\n",
      "\n",
      "[Epoch number : 42, Mini-batches:  1000] loss: 5.090\n",
      "[Epoch number : 42, Mini-batches:  2000] loss: 5.021\n",
      "[Epoch number : 42, Mini-batches:  3000] loss: 5.134\n",
      "[Epoch number : 42, Mini-batches:  4000] loss: 5.113\n",
      "[Epoch number : 42, Mini-batches:  5000] loss: 5.131\n",
      "[Epoch number : 42, Mini-batches:  6000] loss: 5.099\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 67 %\n",
      "\n",
      "[Epoch number : 43, Mini-batches:  1000] loss: 4.968\n",
      "[Epoch number : 43, Mini-batches:  2000] loss: 5.034\n",
      "[Epoch number : 43, Mini-batches:  3000] loss: 5.095\n",
      "[Epoch number : 43, Mini-batches:  4000] loss: 5.175\n",
      "[Epoch number : 43, Mini-batches:  5000] loss: 5.099\n",
      "[Epoch number : 43, Mini-batches:  6000] loss: 5.199\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 67 %\n",
      "\n",
      "[Epoch number : 44, Mini-batches:  1000] loss: 5.122\n",
      "[Epoch number : 44, Mini-batches:  2000] loss: 5.094\n",
      "[Epoch number : 44, Mini-batches:  3000] loss: 5.053\n",
      "[Epoch number : 44, Mini-batches:  4000] loss: 5.118\n",
      "[Epoch number : 44, Mini-batches:  5000] loss: 5.125\n",
      "[Epoch number : 44, Mini-batches:  6000] loss: 5.087\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 68 %\n",
      "\n",
      "[Epoch number : 45, Mini-batches:  1000] loss: 5.004\n",
      "[Epoch number : 45, Mini-batches:  2000] loss: 5.104\n",
      "[Epoch number : 45, Mini-batches:  3000] loss: 5.182\n",
      "[Epoch number : 45, Mini-batches:  4000] loss: 5.023\n",
      "[Epoch number : 45, Mini-batches:  5000] loss: 5.122\n",
      "[Epoch number : 45, Mini-batches:  6000] loss: 5.056\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 66 %\n",
      "\n",
      "[Epoch number : 46, Mini-batches:  1000] loss: 5.044\n",
      "[Epoch number : 46, Mini-batches:  2000] loss: 5.173\n",
      "[Epoch number : 46, Mini-batches:  3000] loss: 5.134\n",
      "[Epoch number : 46, Mini-batches:  4000] loss: 4.978\n",
      "[Epoch number : 46, Mini-batches:  5000] loss: 5.118\n",
      "[Epoch number : 46, Mini-batches:  6000] loss: 5.053\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 67 %\n",
      "\n",
      "[Epoch number : 47, Mini-batches:  1000] loss: 5.053\n",
      "[Epoch number : 47, Mini-batches:  2000] loss: 4.968\n",
      "[Epoch number : 47, Mini-batches:  3000] loss: 5.028\n",
      "[Epoch number : 47, Mini-batches:  4000] loss: 5.106\n",
      "[Epoch number : 47, Mini-batches:  5000] loss: 5.084\n",
      "[Epoch number : 47, Mini-batches:  6000] loss: 5.099\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 66 %\n",
      "\n",
      "[Epoch number : 48, Mini-batches:  1000] loss: 4.947\n",
      "[Epoch number : 48, Mini-batches:  2000] loss: 5.073\n",
      "[Epoch number : 48, Mini-batches:  3000] loss: 5.047\n",
      "[Epoch number : 48, Mini-batches:  4000] loss: 5.097\n",
      "[Epoch number : 48, Mini-batches:  5000] loss: 5.164\n",
      "[Epoch number : 48, Mini-batches:  6000] loss: 5.010\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 64 %\n",
      "\n",
      "[Epoch number : 49, Mini-batches:  1000] loss: 5.069\n",
      "[Epoch number : 49, Mini-batches:  2000] loss: 5.035\n",
      "[Epoch number : 49, Mini-batches:  3000] loss: 5.044\n",
      "[Epoch number : 49, Mini-batches:  4000] loss: 5.109\n",
      "[Epoch number : 49, Mini-batches:  5000] loss: 5.019\n",
      "[Epoch number : 49, Mini-batches:  6000] loss: 5.063\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 67 %\n",
      "\n",
      "[Epoch number : 50, Mini-batches:  1000] loss: 5.016\n",
      "[Epoch number : 50, Mini-batches:  2000] loss: 5.016\n",
      "[Epoch number : 50, Mini-batches:  3000] loss: 5.065\n",
      "[Epoch number : 50, Mini-batches:  4000] loss: 5.076\n",
      "[Epoch number : 50, Mini-batches:  5000] loss: 5.094\n",
      "[Epoch number : 50, Mini-batches:  6000] loss: 5.019\n",
      "\n",
      "LeNet accuracy on 10000 images from test dataset: 68 %\n",
      "\n",
      "Finished Training\n"
     ]
    }
   ],
   "source": [
    "# define optimizer\n",
    "optim = torch.optim.Adam(lenet.parameters(), lr=0.001)\n",
    "\n",
    "# training loop over the dataset multiple times\n",
    "for epoch in range(50):  \n",
    "    train(lenet, trainloader, optim, epoch)\n",
    "    print()\n",
    "    test(lenet, testloader)\n",
    "    print()\n",
    "\n",
    "print('Finished Training')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "model_path = './cifar_model.pth'\n",
    "torch.save(lenet.state_dict(), model_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Label:         cat  ship  ship plane\n",
      "Prediction:    cat  ship  ship  ship\n"
     ]
    }
   ],
   "source": [
    "# load test dataset images\n",
    "d_iter = iter(testloader)\n",
    "im, ground_truth = next(d_iter)\n",
    "\n",
    "# print images and ground truth\n",
    "imageshow(torchvision.utils.make_grid(im[:4]))\n",
    "print('Label:      ', ' '.join('%5s' % classes[ground_truth[j]] for j in range(4)))\n",
    "\n",
    "# load model\n",
    "lenet_cached = LeNet()\n",
    "lenet_cached.load_state_dict(torch.load(model_path))\n",
    "\n",
    "# model inference\n",
    "op = lenet_cached(im)\n",
    "\n",
    "# print predictions\n",
    "_, pred = torch.max(op, 1)\n",
    "\n",
    "print('Prediction: ', ' '.join('%5s' % classes[pred[j]] for j in range(4)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model accuracy on 10000 images from test dataset: 68 %\n"
     ]
    }
   ],
   "source": [
    "success = 0\n",
    "counter = 0\n",
    "with torch.no_grad():\n",
    "    for data in testloader:\n",
    "        im, ground_truth = data\n",
    "        op = lenet_cached(im)\n",
    "        _, pred = torch.max(op.data, 1)\n",
    "        counter += ground_truth.size(0)\n",
    "        success += (pred == ground_truth).sum().item()\n",
    "\n",
    "print('Model accuracy on 10000 images from test dataset: %d %%' % (\n",
    "    100 * success / counter))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model accuracy for class plane : 69 %\n",
      "Model accuracy for class   car : 81 %\n",
      "Model accuracy for class  bird : 56 %\n",
      "Model accuracy for class   cat : 52 %\n",
      "Model accuracy for class  deer : 57 %\n",
      "Model accuracy for class   dog : 49 %\n",
      "Model accuracy for class  frog : 71 %\n",
      "Model accuracy for class horse : 78 %\n",
      "Model accuracy for class  ship : 84 %\n",
      "Model accuracy for class truck : 80 %\n"
     ]
    }
   ],
   "source": [
    "class_sucess = list(0. for i in range(10))\n",
    "class_counter = list(0. for i in range(10))\n",
    "with torch.no_grad():\n",
    "    for data in testloader:\n",
    "        im, ground_truth = data\n",
    "        op = lenet_cached(im)\n",
    "        _, pred = torch.max(op, 1)\n",
    "        c = (pred == ground_truth).squeeze()\n",
    "        for i in range(10000):\n",
    "            ground_truth_curr = ground_truth[i]\n",
    "            class_sucess[ground_truth_curr] += c[i].item()\n",
    "            class_counter[ground_truth_curr] += 1\n",
    "\n",
    "\n",
    "for i in range(10):\n",
    "    print('Model accuracy for class %5s : %2d %%' % (\n",
    "        classes[i], 100 * class_sucess[i] / class_counter[i]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (Local)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
